package models.merchant;

import jodd.bean.BeanCopy;
import jodd.util.StringUtil;
import models.BaseModel;
import models.admin.AdminUser;
import models.constants.DeletedStatus;
import models.merchant.enums.MerchantType;
import models.merchant.enums.VerifyState;
import models.merchant.enums.VisitorType;
import models.weixin.WebUser;
import models.weixin.WeixinData;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import play.modules.paginate.JPAExtPaginator;
import utils.ObjectUtil;

import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 商户 我在本系统中定义为 开在每个商场里面的单店
 * Created by buhaoba on 16/6/16.
 */
@Entity
@Table(name = "power_merchants")
public class Merchant extends BaseModel {

    public static final String CACHE_MERCHANT_LINKId = "ULC_CACHE_MERCHANT_LINKID_";


    /**
     *  登录 用户名
     */
    @Column(name = "login_name")
    public String  loginName;

    /**
     *  登录密码
     */
    @Column(name = "password")
    public String  password;

    /**
     *  验证码
     */
    @Column(name = "verification_code")
    public String  verificationCode;

    /**
     *  验证码获取时间
     */
    @Column(name = "verification_code_at")
    public Date verificationCodeAt;


    /**
     * 商户负责人(WebUser) 以后结算佣金等 都用该用户
     */
    @Column(name = "web_user_id")
    public Long webUserId;

    /**
     * 商户绑定的是哪个微信信息
     */
    @JoinColumn(name = "weixin_datas_id")
    @ManyToOne
    public WeixinData weixinData;

    /**
     * 商户链接编号
     */
    @Column(name = "link_id")
    public String linkId;

    /**
     * 商户设置
     */
    @JoinColumn(name = "set_up")
    @ManyToOne
    public SetUp setUp;

    /**
     * 名称
     */

    @Column(name = "name")
    public String name;

    /**
     * 商户图片
     */
    @Column(name = "image_path")
    public String imagePath;

    /**
     * 商户类型
     */
    @Column(name = "type")
    @Enumerated(EnumType.STRING)
    public MerchantType type;

    /**
     * 最低购买金额
     */
    @Column(name = "min_amount")
    public Float minAmount;

    /**
     * 免运费金额
     */
    @Column(name = "free_freight_amount")
    public Float freeFreightAmount;

    /**
     * 商户可提现金额
     */
    @Column(name = "withdrawals_amount")
    public Double withdrawalsAmount;

    /**
     * 冻结金额
     */
    @Column(name = "frozen_amount")
    public Double frozenAmount;

    /**
     * 是否需要注册
     */
    @Column(name = "need_register")
    public Boolean needRegister;

    /**
     * 访问是否需要授权
     */
    @Column(name = "visit_auth")
    public Boolean visitAuth = Boolean.FALSE;
    /**
     * 是否显示优惠券
     */
    @Column(name="display_coupon")
    public Boolean displayCoupon=Boolean.TRUE;

    /**
     * 是否可用优惠券
     */
    @Column(name="play_coupon")
    public Boolean playCoupon=Boolean.TRUE;

    /**
     * 是否有分享用户 下单后 可获得红包
     */
    @Column(name = "have_share_redbao")
    public Boolean haveShareRedBao = Boolean.FALSE;


    /**
     * 红包金额
     */
    @Column(name = "red_bao_amount")
    public Double redBaoAmount = 1d;

    /**
     * 首页分享朋友圈/微信好友
     */
    @Column(name = "index_share")
    public Boolean indexShare = Boolean.FALSE;

    /**
     * 分享到朋友圈里面的标题
     */
    @Column(name = "share_title")
    public String shareTitle;


    /**
     * 提醒红包
     */
    @Column(name = "index_remind_coupon")
    public Boolean indexRemindCoupon = Boolean.FALSE;


    /**
     * 是否发放赠品
     */
    @Column(name = "offering_freebies")
    public Boolean offeringFreebies = Boolean.FALSE;


    /**
     * 关联的赠送代金券的ID
     */
    @Column(name = "discount_oupon_id")
    public Long discountCouponId;

    /**
     * 客服电话
     */
    @Column(name = "service_phone")
    public String servicePhone;

    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.ORDINAL)
    public DeletedStatus deleted;

    /**
     * 备注
     */
    @Column(name = "remark")
    public String remark;

    /**
     * 审批状态
     */
    @Column(name = "verify_state")
    @Enumerated(EnumType.STRING)
    public VerifyState verifyState;


    /**
     * 身份证或学生证或工作证
     */
    @Column(name = "id_code")
    public String idCode;

    /**
     * 投诉成功次数
     */
    @Column(name = "complaint_count")
    public Integer complaintCount = 0;

    /**
     * 被投诉次数
     */
    @Column(name = "be_complaint_count")
    public Integer beComplaintCount;

    /**
     * 证件照
     */
    @Column(name = "id_img")
    public String idImg;

    /**
     * 分数
     */
    @Column(name = "star_num")
    public Integer starNum;

    /**
     * 真实姓名
     */
    @Column(name = "real_name")
    public String realName;


    /**
     * 微信号
     */
    @Column(name = "we_chat")
    public String weChat;

    /**
     * 指导教师姓名
     */
    @Column(name = "teacher")
    public String teacher;


    /**
     * 团队名称
     */
    @Column(name = "team")
    public String team;


    /**
     * 班级
     */
    @Column(name = "classes")
    public String classes;

    /**
     * 地址
     */
    @Column(name = "address")
    public String address;


    /**
     * 分页查询.
     */
    public static JPAExtPaginator<Merchant> findByCondition(Map<String, Object> conditionMap, String orderByExpress, int pageNumber, int pageSize) {
        StringBuilder xsqlBuilder = new StringBuilder(" t.deleted=models.constants.DeletedStatus.UN_DELETED ")
                .append("/~ and t.name like {merchantName} ~/")
                .append("/~ and t.loginName = {loginName} ~/")
                .append("/~ and t.servicePhone = {phone} ~/")
                .append("/~ and t.verifyState = {verifyState} ~/");
        util.xsql.XsqlBuilder.XsqlFilterResult result = new util.xsql.XsqlBuilder().generateHql(xsqlBuilder.toString(), conditionMap);
                JPAExtPaginator< Merchant > orderPage = new JPAExtPaginator<>("Merchant t", "t", Merchant.class,
                result.getXsql(), conditionMap).orderBy(orderByExpress);
        orderPage.setPageNumber(pageNumber);
        orderPage.setPageSize(pageSize);
        orderPage.setBoundaryControlsEnabled(false);
        return orderPage;
    }


    /**
     * 判断是否有访问权限
     *
     * @return
     */
    public Boolean canVisitor(WebUser wxUser) {
        SetUp setUp = this.setUp;
        // 验证访问者 必须有手机号码
        if (setUp.visitorPhone) {
            if (wxUser == null) {
                return false;
            }
            if (!ObjectUtil.checkNotBlock(wxUser.phone)) {
                return false;
            }
        }

        if (setUp.visitorType != null && setUp.visitorType != VisitorType.WHOLE) {
            if (wxUser == null) {
                return false;
            }
            // 如果设置为商户类型  访问者 只有为一个商户负责人 才能访问
            if (setUp.visitorType == VisitorType.MERCHANT) {
                if (!Merchant.checkByPerson(wxUser)) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Update
     * @param id
     * @param newObject
     */
    public static void update(Long id, Merchant newObject) {
        Merchant merchant= Merchant.findById(id);
        BeanCopy.beans(newObject, merchant).ignoreNulls(true).copy();
        merchant.save();
    }


    /**
     * 跟据LinkId 查询商户信息
     *
     * @param linkId
     * @return
     */
    public static Merchant findByLinkId(final String linkId) {
        return Merchant.find("deleted = ?1 and linkId = ?2", DeletedStatus.UN_DELETED, linkId).first();
    }

    /**
     * 校验模版是否被使用
     *
     * @param id
     * @return
     */
    public static Boolean checkSetUpIsUsed(long id) {
        return Merchant.count("setUp.id=?1 and deleted=?2", id, DeletedStatus.UN_DELETED) > 0;
    }


    /**
     * 校验公众号是否被使用
     *
     * @param id
     * @return
     */
    public static Boolean checkWeixinDataIsUsed(long id) {
        return Merchant.count("weixinData.id=?1 and deleted=?2", id, DeletedStatus.UN_DELETED) > 0;
    }

    public static Boolean checkByPerson(WebUser weixinUser) {
        return Merchant.count("personUser = ?1 and delted = ?2", weixinUser, DeletedStatus.UN_DELETED) > 0 ? true : false;
    }


    public static List<Merchant> findBySetUp(Long setUpId) {
        return Merchant.find("deleted = ?1 and setUp.id = ?2", DeletedStatus.UN_DELETED, setUpId).fetch();
    }

    public static Long countBySetUp(Long setUpId) {
        return Merchant.count("deleted = ?1 and setUp.id = ?2", DeletedStatus.UN_DELETED, setUpId);
    }

    /**
     * 加载所有商户信息
     *
     * @return
     */
    public static List<Merchant> loadAllMerchat() {
        return Merchant.find("deleted=?1", DeletedStatus.UN_DELETED).fetch();
    }
    /**
     * 根据用户数据权限, 查询用户可以看到的商户数据
     * @param adminUser
     * @return
     */
    public static List<Merchant> loadMerchants(AdminUser adminUser){
        return Merchant.find(" deleted=?1 and id in (select AUM.merchant.id from AdminUserMerchant AUM where AUM.adminUser.id = " + adminUser.getId() + ")",DeletedStatus.UN_DELETED).fetch();
    }

    /**
     * 查询所有商户用于生成下拉框
     */
    public static List<Map<String, Object>> loadMerchantsForComoBox() {
        StringBuilder sql = new StringBuilder("select t.id as id ,t.name as name from power_merchants t where t.deleted = '0' order by id desc");
        Query query=em().createNativeQuery(sql.toString());
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, Object>> resultlist = query.getResultList();
        return resultlist;
    }

    public static Merchant findByLinkIdUnCache(String linkId) {
        return Merchant.find("linkId = ?1" , linkId).first();
    }


    public static List<Merchant> findBySetUp(SetUp setUp) {
        return Merchant.find("setUp = ?1" , setUp).fetch();
    }

    /**
     * 获取所有权限范围内的可用商户
     *
     * @return
     */
    public static List<Merchant> findAllAuthMerchant() {
        return Merchant.find("deleted = ?1", DeletedStatus.UN_DELETED).fetch();
    }

    /**
     * 根据Id查询商户
     */
    public static Merchant findByMerchantId(long id) {
        return Merchant.find("id=?1 and deleted=?2", id, DeletedStatus.UN_DELETED).first();
    }

    public static List<Merchant> loadByVisitAuth(){
        return Merchant.find(" deleted = ?1 and visitAuth = 1" , DeletedStatus.UN_DELETED).fetch();
    }

    //判断merchant是否被使用 ,目前判断是否有用户,会员
    public static Boolean checkIsUsed(long merchantId){
        boolean isUsed = false;
        //用户,员工
        long adminUserNum = AdminUser.count("merchant.id = ?1 and deleted = ?2 " , merchantId , DeletedStatus.UN_DELETED);
        if(adminUserNum > 0)
            isUsed = true;
        //会员
        long userNum = WebUser.count("merchant.id = ?1 and deleted = ?2" , merchantId , DeletedStatus.UN_DELETED);
        if(userNum > 0)
            isUsed = true;
        return  isUsed;
    }

    /**
     * 商户名称不能重复
     * @param name
     * @return
     */
    public static Merchant findByName(String name){
        return Merchant.find(" deleted = ?1 and name = ?2 " , DeletedStatus.UN_DELETED , name).first();
    }

    /**
     * 登录名称不能重复
     * @param loginName
     * @return
     */
    public static Merchant findByLoginName(String loginName){
        return Merchant.find(" deleted = ?1 and loginName = ?2 " , DeletedStatus.UN_DELETED , loginName).first();
    }


    public static List<Merchant> findListByName(String keyWord){
        StringBuilder sql = new StringBuilder("select t.id as id ,t.name as name,t.image_path as imagePath, t.link_id as  linkId, t.service_phone servicePhone  from power_merchants t where t.deleted = '0' ");
        sql.append(" and verify_state ='PASS' ");
        if(!keyWord.equals("") && keyWord != null){
            sql.append(" and t.name like '%").append(keyWord).append("%'");
        }
        Query query=em().createNativeQuery(sql.toString());
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Merchant> resultlist = query.getResultList();
        return resultlist;
    }

    /**
     * 根据登录名,手机号,身份证号查询用户
     * @param loginName
     * @param idCode
     * @param phone
     * @return
     */
    public static Merchant findByLoginNameAndPhone(String loginName , String idCode ,String phone){
        return Merchant.find("deleted = 0 and loginName = ?1 and idCode = ?2 and servicePhone = ?3 and verifyState = ?4" , loginName , idCode , phone , VerifyState.PASS).first();
    }
    public static Merchant findMerchantByWebUserId(long webUserId){
        return Merchant.find("deleted = 0 and webUserId = ?1 " , webUserId).first();
    }


    /**
     * 加载所有营业商户信息
     *
     * @return
     */
    public static List<Merchant> loadAllMerchatAndVerifyState() {
        return Merchant.find("deleted=?1 and verifyState = ?2 ", DeletedStatus.UN_DELETED,VerifyState.PASS).fetch();
    }


    /**
     *  按时间统计新增商户
     * @param beginDate
     * @param endDate
     * @return
     */
    public static List<Merchant> findYesterday(Date beginDate, Date endDate) {
        return Merchant.find(" deleted = ?1 and createAt between ?2 and ?3" , DeletedStatus.UN_DELETED ,beginDate,endDate ).fetch();
    }



    /**
     * 商户的产品总销量
     */
    public static List<Map<String, Object>> loadOrderBuyNumberByMerchants(long merId) {
        StringBuilder sql = new StringBuilder("SELECT pm.id , IFNULL(sum(oi.buy_number),0) buyNumber FROM order_items oi ");
        sql.append(" LEFT JOIN goods g ON oi.goods_id = g.id  ");
        sql.append("  LEFT JOIN products p ON p.id = g.serial_id ");
        sql.append("  LEFT JOIN power_merchants pm  on p.merchant_id = pm.id where pm.id = "+merId);
        Query query=em().createNativeQuery(sql.toString());
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, Object>> resultlist = query.getResultList();
        return resultlist;
    }

    /**
     * 商户的销售总额
     */
    public static List<Map<String, Object>> loadSumAmountByMerchants(long merId) {
        StringBuilder sql = new StringBuilder("SELECT pm.id , FORMAT(IFNULL(SUM(oi.amount),0),2) sumAmount  FROM order_items oi ");
        sql.append(" LEFT JOIN goods g ON oi.goods_id = g.id  ");
        sql.append("  LEFT JOIN products p ON p.id = g.serial_id ");
        sql.append("  LEFT JOIN power_merchants pm  on p.merchant_id = pm.id where pm.id = "+merId);
        Query query=em().createNativeQuery(sql.toString());
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, Object>> resultlist = query.getResultList();
        return resultlist;
    }

    /**
     *  导出excle
     * @param merchantName
     * @param phone
     * @param loginName
     * @param verifyState
     * @return
     */
    public static List<Map<String, Object>> loadMerchantsByExcle(String merchantName,String phone,String loginName,VerifyState verifyState) {
        StringBuilder sql = new StringBuilder("select m.name name,m.real_name realName,m.classes classes ,m.service_phone servicePhone,m.we_chat weChat,m.type type,count(p.id) pcount  from power_merchants m   ");
        sql.append(" LEFT JOIN products p on p.merchant_id = m.id  ");
        sql.append("  where p.deleted = 0 and m.deleted = 0 and p.product_status = 'UP' and p.review_status = 'NORMAL' ");
        if(StringUtil.isNotBlank(merchantName)) {
            sql.append("  and m.name like  '%"+merchantName+"%'");
        }
        if(StringUtil.isNotBlank(phone)) {
            sql.append("  and m.service_phone  ='"+phone+"'");
        }
        if(StringUtil.isNotBlank(loginName)) {
            sql.append("  and m.login_name  ='"+loginName+"'");
        }
        if(verifyState != null && !verifyState.equals("")) {
            sql.append("  and m.verify_state  ='"+verifyState+"'");
        }
        sql.append("  GROUP BY m.id ");
        Query query=em().createNativeQuery(sql.toString());
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, Object>> resultlist = query.getResultList();
        return resultlist;
    }




}
